import serial
import os
import time
# 2021-06-18 15:11 by 炸天帮成员
# 修改自 serialPort_demo_0.py
# 即将 serialPort_demo_0.py 的ser.read(100)改为ser.read() + ser.read(ser.waiting)的方式
# 因为如果单纯使用ser.read()，若不设置ser.timeout超时，则会导致COM口阻塞，但ser.waiting()可以获取剩下的字符。

# read(size=1)：读指定字节数，若输入缓冲区中数据小于指定字节数，则等待timeout指定时间，若timeout为None，则一直阻塞。
# in_waiting：输入缓冲区中待读取的字节数。
#----------------------------------------------------------------
# 以下为查询有效的serial_Port
serial_ports = os.popen('python -m serial.tools.list_ports').read().strip() # 调用控制台并读取cmd命令行的结果
print('serial_ports = ',serial_ports)           # 显示当前有效的COM端
#----------------------------------------------------------------
# 以下为常规serial_Port的值
# Default=(port=None,                     – Device name or None.
#               baudrate=9600,(int)         – Baud rate such as 9600 or 115200 etc.
#               bytesize=EIGHTBITS,        – Number of data bits. Possible values: FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS
#               parity=PARITY_NONE,     – Enable parity checking. Possible values: PARITY_NONE, PARITY_EVEN, PARITY_ODD PARITY_MARK, PARITY_SPACE
#               stopbits=STOPBITS_ONE,– Number of stop bits. Possible values: STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO
#               timeout=None,(float)       – Set a read timeout value.
#               xonxoff=False,(bool)        – Enable software flow control.
#               rtscts=False,(bool)           – Enable hardware (RTS/CTS) flow control.
#               write_timeout=None,(float) – Set a write timeout value.
#               dsrdtr=False,                   – Enable hardware (DSR/DTR) flow control.
#               inter_byte_timeout=None(float) – Inter-character timeout, None to disable (default).)
#---------------------------------------------------------------
# 以下为serial_Port设置
ser = serial.Serial()                                   # 实例化serial_com端口
ser.port = serial_ports                             # 设置端口号
ser.baudrate = 115200                           # 设置端口的波特率
ser.bytesize = serial.EIGHTBITS
ser.parity = serial.PARITY_NONE
ser.stopbits = serial.STOPBITS_ONE
ser.timeout = None                                   # 设定读取超时时间 1s
ser.xonxoff=False
ser.rtscts=False
ser.write_timeout= None                           # Set a write timeout value.
ser.dsrdtr=False
ser.inter_byte_timeout=None
print(ser)                                              # 输出当前端口的详细信息
#----------------------------------------------------------------
# 字节串（bytes）和字符串（string）的对比：
# 字符串由若干个字符组成，以字符为单位进行操作；字节串由若干个字节组成，以字节为单位进行操作。
# 字节串和字符串除了操作的数据单元不同之外，它们支持的所有方法都基本相同。
# 字节串和字符串都是不可变序列，不能随意增加和删除数据。

# bytes 只负责以字节序列的形式（二进制形式）来存储数据，至于这些数据到底表示什么内容（字符串、数字、图片、音频等），完全由程序的解析方式决定。如果采用合适的字符编码方式（字符集），字节串可以恢复成字符串；反之亦然，字符串也可以转换成字节串。

# 说白了，bytes 只是简单地记录内存中的原始数据，至于如何使用这些数据，bytes 并不在意，你想怎么使用就怎么使用，bytes 并不约束你的行为。

# bytes 类型的数据非常适合在互联网上传输，可以用于网络通信编程；bytes 也可以用来存储图片、音频、视频等二进制格式的文件。

# 字符串和 bytes 存在着千丝万缕的联系，我们可以通过字符串来创建 bytes 对象，或者说将字符串转换成 bytes 对象。有以下三种方法可以达到这个目的：
# 如果字符串的内容都是 ASCII 字符，那么直接在字符串前面添加b前缀就可以转换成 bytes。
# bytes 是一个类，调用它的构造方法，也就是 bytes()，可以将字符串按照指定的字符集转换成 bytes；如果不指定字符集，那么默认采用 UTF-8。
# 字符串本身有一个 encode() 方法，该方法专门用来将字符串按照指定的字符集转换成对应的字节串；如果不指定字符集，那么默认采用 UTF-8。
#------------------------------------------------------------------
# 以下为读写serial_Port，串口的发送内容必须要为bytes类型字符串

def sendStringToESP8266(theContent:str):
    send_bytes = bytes(theContent,encoding='UTF-8')+b'\x0d\x0a'
    send_string = send_bytes.decode('UTF-8')
    print('send_bytes = ',send_bytes,'send_bytes 的类型为：',type(send_bytes),'\nsend_string = ',send_string,' send_string 的类型为',type(send_string))
    ser.write(send_bytes)                      # 发送数据至ESP8266
    
    data_return = ser.read()                        # 按字节数读取来自下位机的串口内容，此处设定为100字节
    print('data_return = ',data_return)       # 显示从COM端读取到的内容
    data_in_waiting = ser.read(ser.in_waiting)
    print('ser.in_waiting =',data_in_waiting)
    result = data_return + data_in_waiting
    print('esp8266结果为：',result.decode(encoding="UTF-8"))

ser.open()                                            # 开启端口
if ser.is_open :
##    send_bytes = bytes("import machine",encoding='UTF-8')+b'\x0d\x0a'
##    send_string = send_bytes.decode('UTF-8')
##    print('send_bytes = ',send_bytes,'send_bytes 的类型为：',type(send_bytes),'\nsend_string = ',send_string,' send_string 的类型为',type(send_string))
##    ser.write(send_bytes)                      # 发送数据至下位机
##    
##    data_return = ser.read()                 # 按字节数读取来自下位机的串口内容，此处设定为100字节
##    print('data_return = ',data_return)       # 显示从COM端读取到的内容
##    data_in_waiting = ser.read(ser.in_waiting)
##    print('ser.in_waiting =',data_in_waiting)
##    result = data_return + data_in_waiting
##    print('最终结果为：',result.decode(encoding="GBK"))
##
    sendStringToESP8266("import machine")
##    #------
##    send_bytes = bytes("machine.freq()",encoding='UTF-8')+b'\x0d\x0a'
##    send_string = send_bytes.decode('UTF-8')
##    print('send_bytes = ',send_bytes,'send_bytes 的类型为：',type(send_bytes),'\nsend_string = ',send_string,' send_string 的类型为',type(send_string))
##    ser.write(send_bytes)                      # 发送数据至下位机
##
##    data_return = ser.read()                 # 按字节数读取来自下位机的串口内容，此处设定为100字节
##    print('data_return = ',data_return)       # 显示从COM端读取到的内容
##    data_in_waiting = ser.read(ser.in_waiting)
##    print('ser.in_waiting =',data_in_waiting)
##    result = data_return + data_in_waiting
##    print('最终结果为：',result.decode(encoding="UTF-8"))
    sendStringToESP8266("machine.freq()")

ser.close()
